﻿using System;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using YooAsset;
using Cysharp.Threading.Tasks;
using UnityEngine;
using Object = UnityEngine.Object;

namespace LitFramework
{
    /// <summary>
    /// 资源管理类
    /// </summary>
    public class AssetManager : Singleton<AssetManager>, ISingleton
    {
        private ResourcePackage package;
        private Dictionary<string, AssetHandle> assetHandlerDict;
        private Dictionary<string, SceneHandle> sceneHandleDict;

        void ISingleton.OnInit()
        {
            assetHandlerDict = new Dictionary<string, AssetHandle>();
            sceneHandleDict = new Dictionary<string, SceneHandle>();
            package = YooAssets.GetPackage(ProjectConfig.Config.packageName);
        }

        void ISingleton.OnDestroy()
        {
            package = null;
        }

        /// <summary>
        /// 加载资源
        /// </summary>
        /// <param name="path"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async UniTask<T> LoadAsset<T>(string path) where T : Object
        {
            if (assetHandlerDict.TryGetValue(path, out var handler))
            {
                return handler.AssetObject as T;
            }

            handler = package.LoadAssetAsync(path);
            assetHandlerDict.Add(path, handler);
            await handler.Task;
            return handler.AssetObject as T;
        }

        /// <summary>
        /// 卸载资源
        /// </summary>
        /// <param name="path"></param>
        public void UnloadAsset(string path)
        {
            if (assetHandlerDict.TryGetValue(path, out var handle))
            {
                assetHandlerDict.Remove(path);
                handle.Release();
            }
        }

        /// <summary>
        /// 加载场景
        /// </summary>
        /// <param name="path"></param>
        /// <param name="sceneMode"></param>
        /// <returns></returns>
        public async UniTask<Scene> LoadScene(string path, LoadSceneMode sceneMode)
        {
            if (sceneHandleDict.TryGetValue(path, out var handle))
            {
                return handle.SceneObject;
            }

            bool suspendLoad = false;
            handle = package.LoadSceneAsync(path, sceneMode, suspendLoad);
            await handle.Task;
            return handle.SceneObject;
        }

        /// <summary>
        /// 卸载场景
        /// </summary>
        /// <param name="path"></param>
        public async void UnloadScene(string path)
        {
            if (sceneHandleDict.TryGetValue(path, out var handle))
            {
                await handle.UnloadAsync();
            }
        }

        /// <summary>
        /// 卸载所有未使用的资源
        /// </summary>
        public void UnloadUnusedAssets()
        {
            package.UnloadUnusedAssets();
            assetHandlerDict.Clear();
        }
    }
}